package com.george.reversing;

import java.io.File;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;

import com.george.reversing.util.Connector;
import com.george.reversing.util.FileConnector;
import com.george.reversing.util.RWThreadCallback;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Process;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class MyService extends Service  implements RWThreadCallback{

	/**
	 * 自定义窗口
	 */
	private MyWindow myWindow;
	/**
	 * 窗口管理者
	 */
	private WindowManager mWindowManager;
	/**
	 * 窗口布局参数
	 */
	private LayoutParams Params;
	
	private View mCheckFullScreenView = null;
	
	private Connector mConnectedThread = null;
	private static final short CMD_IN_CAR_INFO = 0x01;
	private static final short CMD_IN_RADAR = 0x02;
	
	private static final byte CAR_INFO_POWER = 0x01;
	private static final byte CAR_INFO_ACC = 0x02;
	private static final byte CAR_INFO_REVERSING = 0x04;
	private Thread mRecvThread = null;
	private LinkedList<byte[]> mReceiveList = new LinkedList<byte[]>();
	private volatile boolean mbThreadStop = false;
	private boolean mReversing;
	private RelativeLayout mRadarLayout;
	private ImageView mReversingLine;
	private ImageView mTopImage;
	private ImageView mBottomImage;
	private int reversing_line = 0;
	private int reversing_line_res = R.drawable.l_c_r;
	
	private static final String CFG_CAN_FLAG = "can_flag";
	private int mCanFlag = 0x03;
	private static final int BACKUPLINEFLAG = 0x02;
    private static final int RADARFLAG = 0x04;
	
	
	private short radar[] = {0,0,0,0,0,0,0,0};
	private ImageView radars_bitmaps[] =new ImageView[8] ;
	private int radar_f1[] = {
			R.drawable.f_l_1,
			R.drawable.f_l_2,
			R.drawable.f_l_3,
			R.drawable.f_l_4,
			R.drawable.f_l_5,
			R.drawable.f_l_6,
	};
	
	private int radar_f2[] = {
			R.drawable.f_cl_1,
			R.drawable.f_cl_2,
			R.drawable.f_cl_3,
			R.drawable.f_cl_4,
			R.drawable.f_cl_5,
			R.drawable.f_cl_6,
			R.drawable.f_cl_7,
			R.drawable.f_cl_8,
	};

	private int radar_f3[] = {
			R.drawable.f_cr_1,
			R.drawable.f_cr_2,
			R.drawable.f_cr_3,
			R.drawable.f_cr_4,
			R.drawable.f_cr_5,
			R.drawable.f_cr_6,
			R.drawable.f_cr_7,
			R.drawable.f_cr_8,
	};
	private int radar_f4[] = {
			R.drawable.f_r_1,
			R.drawable.f_r_2,
			R.drawable.f_r_3,
			R.drawable.f_r_4,
			R.drawable.f_r_5,
			R.drawable.f_r_6,
	};
	
	private int radar_b1[] = {
			R.drawable.b_l_1,
			R.drawable.b_l_2,
			R.drawable.b_l_3,
			R.drawable.b_l_4,
	};
	
	private int radar_b2[] = {
			R.drawable.b_cl_1,
			R.drawable.b_cl_2,
			R.drawable.b_cl_3,
			R.drawable.b_cl_4,
			R.drawable.b_cl_5,
			R.drawable.b_cl_6,
			R.drawable.b_cl_7,
			R.drawable.b_cl_8,
	};

	private int radar_b3[] = {
			R.drawable.b_cr_1,
			R.drawable.b_cr_2,
			R.drawable.b_cr_3,
			R.drawable.b_cr_4,
			R.drawable.b_cr_5,
			R.drawable.b_cr_6,
			R.drawable.b_cr_7,
			R.drawable.b_cr_8,
	};
	private int radar_b4[] = {
			R.drawable.b_r_1,
			R.drawable.b_r_2,
			R.drawable.b_r_3,
			R.drawable.b_r_4,
	};

	private int radars_images[][] = {radar_f1,radar_f2,radar_f3,radar_f4,radar_b1,radar_b2,radar_b3,radar_b4};
	private int reversing_line_l[] = {
			R.drawable.l_1,
			R.drawable.l_2,
			R.drawable.l_3,
			R.drawable.l_4,
			R.drawable.l_5,
			R.drawable.l_6,
			R.drawable.l_7,
			R.drawable.l_8,
			R.drawable.l_9,
			R.drawable.l_10,
			R.drawable.l_11,
			R.drawable.l_12,
			R.drawable.l_13,
			R.drawable.l_14,
			R.drawable.l_15,
			R.drawable.l_16,
			R.drawable.l_17,
			R.drawable.l_18,
			R.drawable.l_19,
			R.drawable.l_20};
	private int reversing_line_r[] = {
			R.drawable.r_1,
			R.drawable.r_2,
			R.drawable.r_3,
			R.drawable.r_4,
			R.drawable.r_5,
			R.drawable.r_6,
			R.drawable.r_7,
			R.drawable.r_8,
			R.drawable.r_9,
			R.drawable.r_10,
			R.drawable.r_11,
			R.drawable.r_12,
			R.drawable.r_13,
			R.drawable.r_14,
			R.drawable.r_15,
			R.drawable.r_16,
			R.drawable.r_17,
			R.drawable.r_18,
			R.drawable.r_19,
			R.drawable.r_20};
	
	
	private Handler handler = new Handler() {
	public void handleMessage(Message msg) {

			if (isReversing()) {
				// 如果回到桌面,则显示悬浮窗
				mCanFlag = Settings.System.getInt(getApplicationContext().getContentResolver(), CFG_CAN_FLAG, mCanFlag);
				mRadarLayout.setVisibility(((mCanFlag & RADARFLAG) == RADARFLAG)?View.VISIBLE:View.GONE);
				mReversingLine.setVisibility(((mCanFlag & BACKUPLINEFLAG) == BACKUPLINEFLAG)?View.VISIBLE:View.GONE);
				if (!myWindow.isAttachedToWindow()) {
					 int[] top = new int[2];
						mCheckFullScreenView.getLocationOnScreen(top);
						if (top[1] == 0) {
							Params.x = 0;
							Params.y = 0;
						}else {
							Params.x = 0;
							Params.y = -top[1];
						}
					mWindowManager.addView(myWindow, Params);
				}

			} else {
				// 如果在非桌面,则去掉悬浮窗
				if (myWindow.isAttachedToWindow()) {
					mWindowManager.removeView(myWindow);
				}
			}
			super.handleMessage(msg);
		};
	};

	@Override
	public IBinder onBind(Intent arg0) {

		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		// 定时器类
		Context ctx = getApplicationContext();
        mCheckFullScreenView = new View(ctx);
        mCheckFullScreenView.setBackgroundColor(Color.TRANSPARENT);
        WindowManager windowManager = (WindowManager)ctx.getSystemService(WINDOW_SERVICE);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        //创建非模态、不可碰触
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                |WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        //放在左上角
        params.gravity = Gravity.START | Gravity.TOP;
        params.height = 1;
        params.width = 1;
        //设置弹出View类型
        params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;

        windowManager.addView(mCheckFullScreenView, params);
		Timer timer = new Timer();
		timer.schedule(task, 1000, 1000); // 1s后执行task,经过1s再次执行
		
		//对于6.0以上的设备
		if (Build.VERSION.SDK_INT >= 23) {
			//如果支持悬浮窗功能
			if (Settings.canDrawOverlays(getApplicationContext())) {
				 showWindow();
			} else {
				//手动去开启悬浮窗
				Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				getApplicationContext().startActivity(intent);
			}
		} else {
				//6.0以下的设备直接开启
				showWindow();
		}
		
		mConnectedThread = (Connector) new FileConnector(new File("/dev/systeminit"), this);
		mConnectedThread.start();
	}

	private void showWindow() {
		//创建MyWindow的实例
		myWindow = new MyWindow(getApplicationContext());
		mReversingLine = (ImageView) myWindow.findViewById(R.id.revers_lines);
		mRadarLayout =  (RelativeLayout) myWindow.findViewById(R.id.radar_layout);
		radars_bitmaps[0]  = (ImageView) myWindow.findViewById(R.id.top_image);
		radars_bitmaps[1]  = (ImageView) myWindow.findViewById(R.id.top_image1);
		radars_bitmaps[2]  = (ImageView) myWindow.findViewById(R.id.top_image2);
		radars_bitmaps[3]  = (ImageView) myWindow.findViewById(R.id.top_image3);
		radars_bitmaps[4] =  (ImageView) myWindow.findViewById(R.id.bottom_image);
		radars_bitmaps[5] =  (ImageView) myWindow.findViewById(R.id.bottom_image1);
		radars_bitmaps[6] =  (ImageView) myWindow.findViewById(R.id.bottom_image2);
		radars_bitmaps[7] =  (ImageView) myWindow.findViewById(R.id.bottom_image3);
		
		//窗口管理者
		mWindowManager = (WindowManager) getSystemService(Service.WINDOW_SERVICE);
		//窗口布局参数
		Params = new WindowManager.LayoutParams();
		//布局坐标,以屏幕左上角为(0,0)
		
		Params.x = 0;
		Params.y = 0;
		//布局类型
		Params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 系统提示类型,重要
		
		//布局flags
		Params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 不能抢占聚焦点
		Params.flags = Params.flags | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
		Params.flags = Params.flags | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; // 排版不受限制
		Params.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;

		//布局的gravity
		Params.gravity = Gravity.LEFT | Gravity.TOP;
 
		//布局的宽和高
//		Params.width =  855;
//		Params.height = 480;
		Params.width =  1280;
		Params.height = 480;
//		Params.width =  1920;
//		Params.height = 1080;


		myWindow.setOnTouchListener(new OnTouchListener() {
 
			@Override
			public boolean onTouch(View v, MotionEvent event) {
			 	switch (event.getAction()) {				
			 	
			 	case MotionEvent.ACTION_MOVE:
					Params.x = (int) event.getRawX() - myWindow.getWidth() / 2;
					Params.y = (int) event.getRawY() - myWindow.getHeight() / 2;
					//更新布局位置
					mWindowManager.updateViewLayout(myWindow, Params);
					
					break;
				}
			 	return false;
			}
		 });

	}

	//定时发送message给Handler
	TimerTask task = new TimerTask() {
		@Override
		public void run() {
			Message message = new Message();
			handler.sendMessage(message);
		}
	};

	


	/**
	 * @return 判断当前是否是桌面
	 */
	public boolean isReversing() {
		return mReversing;
	}
	
	@Override
	public void connectError() {
		
	}
	@Override
    public void ThreadRun() {
		mbThreadStop = false;
		if (mRecvThread == null) {
			mRecvThread = new Thread(mRevRunnable, "data-receive");
			mRecvThread.setPriority(Process.THREAD_PRIORITY_BACKGROUND);
		}
		mRecvThread.start();
	}
	private Runnable mRevRunnable = new Runnable() {

		@Override
		public void run() {
			while (!mbThreadStop) {
				try {
					synchronized (mReceiveList) {
						if (mReceiveList.size() == 0) {
							mReceiveList.wait();
						}
						if (mReceiveList.size() > 0) {
							handleProc(mReceiveList.pollFirst());
						}
					}
					Thread.sleep(5);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	};
	
	/**
	 * handle/dispatch data from receive thread
	 * 
	 * @param buffer
	 */
	private void handleProc(byte[] data) {
		if (data != null) {
			final short id = (short) (data[2] & 0xff);
			if(id == CMD_IN_CAR_INFO) {
				final short subid = (short) (data[3] & 0xff);
				if ((subid & CAR_INFO_REVERSING) == CAR_INFO_REVERSING) {
					mReversing = true;
				}else {
					mReversing = false;
				}
			}
			if(id == CMD_IN_RADAR) {
				final short reversing = (short) (data[3] & 0xff);
				final short radars[] = new short[8];
				for(int i=0;i<8;i++) {
					radars[i] =  (short) (data[4+i] & 0xff);
				}
				for(int i=0;i<8;i++) {
					if(radar[i]!=radars[i]) {
						radar[i] =radars[i];
						final ImageView tmp = radars_bitmaps[i];
						final int j = i;
						final short radar_tmp = radar[i];
						radars_bitmaps[i].post(new Runnable() {
							
							@Override
							public void run() {
								try {
									tmp.setImageResource(radars_images[j][radar_tmp]);
								}catch (Exception e) {
									// TODO: handle exception
								}
							}
						});
					}
				}
				if(reversing != reversing_line) {
					reversing_line = reversing;
					if(reversing_line==0) {
						reversing_line_res = R.drawable.l_c_r;
						
					}else if((reversing_line&0x80)==0x80) {
						int index = reversing_line &0x7f;
						if(index>=0&&index<=19)
						reversing_line_res = reversing_line_r[index];
					}else {
						int index = reversing_line;
						if(index>=0&&index<=19)
							reversing_line_res = reversing_line_l[index];
					}
					Log.e("RWThread","  reversing = "+reversing+"   reversing_line_res="+reversing_line_res);
					mReversingLine.post(new Runnable() {
						
						@Override
						public void run() {
							mReversingLine.setImageResource(reversing_line_res);
							
						}
					});
				}
			}
			
		}
	}
	
	@Override
    public void parseProtocol(byte[] buffer, int bytes) {
		pushRevList(buffer);
	}
	
	protected void pushRevList(byte[] data) { 
		try {
			synchronized (mReceiveList) {
				mReceiveList.add(data);
				mReceiveList.notifyAll();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


}
